define([
  'jquery', './namespace'
], function($, Ipenta) {

  var _routes = {},
    _filters,
    defaultRouter = function() {
      console.log(404);
    };

  var Route = Ipenta.Route = {
    init: function(map, filters) {
      register(map);
      if (filters) {
        _filters = filter(filters);
      }
      listen();
      onchange;
    }
  };

  var register = function(map) {
    var _defaultRouter = map['*'];
    if (_defaultRouter) {
      defaultRouter = _defaultRouter;
      delete map['*'];
    }
    _routes = map;
  }

  var onchange = function(onChangeEvent) {
    var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
    var url = newURL.replace(/.*#/, '');
    var found = false;
    for (var path in _routes) {
      var reg = getRegExp(path);
      var result = reg.exec(url);
      if (result && result[0] && result[0] != '') {
        var _handler = _routes[path];
        _handler && _handler.apply(null, result.slice(1));
        found = true;
      }
    }
    if (!found && defaultRouter) {
      defaultRouter();
    }
  };

  /**
   * 引自backbone，正则判断:https://github.com/jashkenas/backbone
   * @param route
   * @returns {RegExp}
   */
  var getRegExp = function(route) {
    var optionalParam = /\((.*?)\)/g;
    var namedParam = /(\(\?)?:\w+/g;
    var splatParam = /\*\w+/g;
    var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
    route = route.replace(escapeRegExp, '\\$&').replace(optionalParam, '(?:$1)?').replace(namedParam, function(match, optional) {
      return optional
        ? match
        : '([^/?]+)';
    }).replace(splatParam, '([^?]*?)');
    return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
  }

  /**
   * 引自director：https://github.com/flatiron/director
   */
  function listen() {
    if ('onhashchange' in window && (document.documentMode === undefined || document.documentMode > 7)) {
      // At least for now HTML5 history is available for 'modern' browsers only
      if (this.history === true) {
        // There is an old bug in Chrome that causes onpopstate to fire even
        // upon initial page load. Since the handler is run manually in init(),
        // this would cause Chrome to run it twise. Currently the only
        // workaround seems to be to set the handler after the initial page load
        // http://code.google.com/p/chromium/issues/detail?id=63040
        setTimeout(function() {
          window.onpopstate = onchange;
        }, 500);
      } else {
        window.onhashchange = onchange;
      }
      this.mode = 'modern';
    } else {
      throw new Error('sorry, your browser doesn\'t support route');
    }
  }

  return {'Route': Route};

});
